Makefile: suppress ld RWX LOAD segment warning for loader.elf#1406
Conversation
When building loader.elf, ld.bfd now emits:
ld.bfd: warning: build/release.x64/loader.elf has a LOAD segment
with RWX permissions
This warning was introduced in binutils 2.39 (August 2022) as a
security-hardening measure to encourage W^X (Write XOR Execute)
policies in userspace binaries. Many distros have shipped binutils
2.39 or later since 2023, so the warning now appears for most users.
The warning is a false positive for OSv. Our linker script
(arch/x64/loader.ld) deliberately places all sections -- .text, .data,
.bss, and friends -- into a single PT_LOAD segment. This is an
intentional kernel design: the loader bootstraps the MMU and enforces
its own page-level permissions after it is running; the ELF segment
permissions are irrelevant at that point.
The "correct" fix would be to split loader.ld into two PT_LOAD
segments -- one RX for code and one RW for data -- as W^X would
require. However, that change is harder to reason about: OSv's loader
relies on the precise VA/PA layout expressed via AT(ADDR(s) -
OSV_KERNEL_VM_SHIFT) throughout the linker script, and splitting the
single contiguous segment could affect relocation handling, the ELF
header placement, and early-boot assumptions that have never been
tested with a multi-segment layout. Proper W^X support for the kernel
image is tracked in issue cloudius-systems#651; we defer it to that effort.
For now, detect whether ld.bfd supports --no-warn-rwx-segments (added
in the same binutils 2.39 release that introduced the warning) and, if
so, pass it when linking loader.elf and zfs_builder.elf. On older
toolchains the flag is absent and the build is unaffected.
There was a problem hiding this comment.
Pull request overview
This PR updates the build system to suppress the GNU ld.bfd “RWX LOAD segment” warning (introduced in binutils 2.39) when linking OSv’s loader.elf (and zfs_builder.elf), since OSv intentionally uses a single RWX PT_LOAD segment during early boot.
Changes:
- Adds ld.bfd capability detection for
--no-warn-rwx-segments. - Conditionally appends
--no-warn-rwx-segmentsto the linker options used forloader.elfandzfs_builder.elf.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ld_no_warn_rwx := $(shell $(LD) --no-warn-rwx-segments 2>&1 | grep -c "unrecognized option") | ||
| ifeq ($(ld_no_warn_rwx),0) | ||
| conf_linker_extra_options += --no-warn-rwx-segments | ||
| endif |
|
This one and my #1405 and #1409 are three independent symptoms of the same underlying cause: newer binutils (I hit all three on binutils 2.46) tightened its handling of LOAD segments and section layout, and OSv's linker scripts predate those changes. They do not overlap in the files they touch and none is a substitute for the others; a build on a recent toolchain needs all three. I just built the current master on binutils 2.46 and hit them in this exact order:
So the relationship is: #1409 and #1405 are the two hard link failures that stop a build cold on modern binutils (one in Separately, on the feature-detection robustness point Copilot raised here: matching the English string "unrecognized option" is locale- and linker-dependent. Scanning |
|
This is worth finishing. binutils 2.39+ emits the One robustness point on the probe, which is also what Copilot flagged: matching the English string ld_no_warn_rwx := $(shell $(LD) --help 2>&1 | grep -c -- --no-warn-rwx-segments)
ifneq ($(ld_no_warn_rwx),0)
conf_linker_extra_options += --no-warn-rwx-segments
endif
Heads up on merge ordering: #1409 also adds lines to the top of the Makefile, so whichever of the two lands second will need a trivial rebase. No textual conflict in the bodies, just adjacent insertions. |
When building loader.elf, ld.bfd now emits:
ld.bfd: warning: build/release.x64/loader.elf has a LOAD segment
with RWX permissions
This warning was introduced in binutils 2.39 (August 2022) as a security-hardening measure to encourage W^X (Write XOR Execute) policies in userspace binaries. Many distros have shipped binutils 2.39 or later since 2023, so the warning now appears for most users.
The warning is a false positive for OSv. Our linker script (arch/x64/loader.ld) deliberately places all sections -- .text, .data, .bss, and friends -- into a single PT_LOAD segment. This is an intentional kernel design: the loader bootstraps the MMU and enforces its own page-level permissions after it is running; the ELF segment permissions are irrelevant at that point.
The "correct" fix would be to split loader.ld into two PT_LOAD segments -- one RX for code and one RW for data -- as W^X would require. However, that change is harder to reason about: OSv's loader relies on the precise VA/PA layout expressed via AT(ADDR(s) - OSV_KERNEL_VM_SHIFT) throughout the linker script, and splitting the single contiguous segment could affect relocation handling, the ELF header placement, and early-boot assumptions that have never been tested with a multi-segment layout. Proper W^X support for the kernel image is tracked in issue #651; we defer it to that effort.
For now, detect whether ld.bfd supports --no-warn-rwx-segments (added in the same binutils 2.39 release that introduced the warning) and, if so, pass it when linking loader.elf and zfs_builder.elf. On older toolchains the flag is absent and the build is unaffected.